package com.social.socialservice.dal;

import com.social.socialservice.idal.IUserDAL;
import com.social.socialservice.model.*;
import com.social.socialservice.unit.EncryptHelper;
import com.social.socialservice.unit.Pager;
import com.social.socialservice.unit.Response;
import com.social.socialservice.unit.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;

/**
 * 用户接口实现层
 */
@Service
public class UserDAL {
    @Autowired
    IUserDAL iUserDAL;

    @Autowired
    NotifyDAL notifyDAL;

    /**
     * 用户注册功能
     * 1. 判断用户名和注册邮箱是否已使用，使用过的不可以注册
     * 2. 用户输入邮箱注册，邮箱发送验证码，输入验证码正确之后进行注册
     * 3. 添加新的用户账户
     */
    public Response RegUser(UserInfo userInfo) {

        if (validateUser(userInfo)) {
            return new Response(203, "用户名已经存在", null);
        }
        if (validateUserEmail(userInfo)) {
            return new Response(203, "邮箱已经存在", null);
        }
        if (validateCode(userInfo)) {
            if (AddUser(userInfo)) {
                return new Response(200, "注册成功", null);
            } else {
                return new Response(203, "注册失败", null);
            }
        } else {
            return new Response(203, "邮箱验证码错误", null);
        }
    }

    /**
     * 获取邮箱验证码
     *
     * @param userInfo
     * @return
     */
    public String getEmailValidateCode(UserInfo userInfo) {
        return "";
    }

    /**
     * 生成注册验证码
     * 用于用户注册使用
     */
    public boolean setValidateCode(UserInfo userInfo) {
        if (iUserDAL.setValidateCode(userInfo) > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 验证注册验证码
     * 返回true说明存在
     */
    public boolean validateCode(UserInfo userInfo) {
        System.out.println(iUserDAL.validateCode(userInfo));
        if (iUserDAL.validateCode(userInfo) > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 验证用户名是否存在
     *
     * @param userInfo
     * @return
     */
    private boolean validateUser(UserInfo userInfo) {
        if (iUserDAL.validateUser(userInfo) > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 验证注册邮箱是否已经使用过
     *
     * @param userInfo
     * @return
     */
    private boolean validateUserEmail(UserInfo userInfo) {
        if (iUserDAL.validateUserEmail(userInfo) > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 添加用户信息
     *
     * @param userInfo 添加成功返回true，失败返回false
     */
    private boolean AddUser(UserInfo userInfo) {
        //对用户密码进行加密
        userInfo.setUser_pass(EncryptHelper.SHA(userInfo.getUser_pass()));
        if (iUserDAL.AddUser(userInfo) > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 用户登录功能 - token认证
     * 1. 判断用户名和密码是否正确 - 前端判断
     * 2. 判断当前登录用户是否处于禁用状态 - 该状态不可登录
     * 3. 判断当前登录用户是否处于禁言状态 - 可登录带着该状态参数不能发言
     */
    public Response LoginUser(UserInfo userInfo) {
        //登录密码加密
        userInfo.setUser_pass(EncryptHelper.SHA(userInfo.getUser_pass()));
        //多用户名 邮箱
        userInfo.setUser_email(userInfo.getUsername());
        UserInfo user = iUserDAL.LoginUser(userInfo);
        if (user != null) {
            //装载登录记录信息
            recodeLoginUser(user.getUser_id(), userInfo);
            //存放登录token
            String token = TokenUtils.sign(user);
            HashMap<String, Object> hs = new HashMap<>();
            hs.put("token", token);
            hs.put("user", user);
            return new Response(200, "登录成功", hs);
        } else {
            return new Response(203, "登录失败，请重新登录", null);
        }
    }

    /**
     * 封装记录用户登录信息方法
     */
    private void recodeLoginUser(Integer user_id, UserInfo userInfo) {
        //登录成功进行登录记录
        LoginRecordInfo loginRecord = new LoginRecordInfo();
        //将登录成功的用户id存入记录对象
        loginRecord.setUser_id(user_id);
        //这里将登录成功用户的IP地址信息存入，这里需要借助外部方法实现
        loginRecord.setLogin_ip(userInfo.getLogin_ip());
        loginRecord.setLogin_lan_ip(userInfo.getLogin_lan_ip());
        loginRecord.setLogin_country(userInfo.getLogin_country());
        loginRecord.setLogin_city(userInfo.getLogin_city());
        loginRecord.setLogin_regionName(userInfo.getLogin_regionName());
        loginRecord.setLogin_location(userInfo.getLogin_location());
        loginRecord.setLogin_lat(userInfo.getLogin_lat());
        loginRecord.setLogin_lon(userInfo.getLogin_lon());
        //执行用户记录方法 后期该方法可以进行封装
        addUserLoginRecord(loginRecord);
    }

    /**
     * 用户登录成功后记录用户登录信息
     * 登录时间、地点、IP地址等
     */
    private boolean addUserLoginRecord(LoginRecordInfo loginRecordInfo) {
        if (iUserDAL.addUserLoginRecord(loginRecordInfo) > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 密码找回
     * 验证用户名或者邮箱是否存在，如果存在则发送重置链接到用户邮箱
     */
    public UserInfo getResetLink(UserInfo userInfo) {
        return iUserDAL.getResetLink(userInfo);
    }

    /**
     * 密码找回验证成功后
     * 重置用户表中验证码及验证码生成时间
     */
    public boolean resetCode(UserInfo userInfo) {
        if (iUserDAL.resetCode(userInfo) > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 密码找回
     * 通过验证重置码，修改个人密码
     * 通过用户名或邮箱地址二选一，并且验证码要正确才可以修改
     */
    public Response resetUserPass(UserInfo userInfo) {
        //可以邮箱更新
        userInfo.setUser_email(userInfo.getUsername());
        //密码加密
        userInfo.setUser_pass(EncryptHelper.SHA(userInfo.getUser_pass()));
        if (iUserDAL.resetUserPass(userInfo) > 0) {
            return new Response(200, "密码重置成功", null);
        } else {
            return new Response(203, "密码重置失败", null);
        }
    }

    /**
     * 登录后
     * 根据user_id获取用户动态信息
     * 关注者/被关注者/个性简介等
     */
    public Response getInfoByUserId(UserInfo userInfo) {
        return new Response(200, "查询成功", iUserDAL.getInfoByUserId(userInfo));
    }

    /**
     * 用户修改非敏感信息,个人资料
     * 1. 背景图片-可选
     * 2. 头像-可选
     * 3. 其他表单数据
     */
    public boolean EditUserInfo(UserInfo userInfo) {
        if (iUserDAL.EditUserInfo(userInfo) > 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 与帖子转发、点赞状态一起，查询当前发帖的用户是否被当前登录用户关注
     * 当前用户是否关注了对方
     */
    public Integer getIsFoByCurrentUserId(FansListInfo fansListInfo) {
        return iUserDAL.getIsFoByCurrentUserId(fansListInfo);
    }

    /**
     * 当前用户是否被关注
     * 用户id互换
     */
    public Integer getByFoByPostUserId(FansListInfo fansListInfo) {
        return iUserDAL.getByFoByPostUserId(fansListInfo);
    }

    /**
     * 关注功能整合，包含关注、被关注，互相关注
     * 未关注：0
     * 关注：1
     * 互相关注：2
     * 被关注：3
     */
    public Response getIsForByCurrentUserId(FansListInfo fansListInfo) {
        //第一步判断是否互相关注
        if (getIsFoByCurrentUserId(fansListInfo) > 0 && getByFoByPostUserId(fansListInfo) > 0) {
            //互相关注
            return new Response(200, "互相关注", 2);
        }
        //当前用户关注了发帖人
        if (getIsFoByCurrentUserId(fansListInfo) > 0) {
            return new Response(200, "正在关注", 1);
        }
        //当前发帖人关注了当前用户
        if (getByFoByPostUserId(fansListInfo) > 0) {
            return new Response(200, "正被关注", 3);
        }
        //双方都没有相互关注
        return new Response(200, "关注", 0);
    }

    /**
     * 关注用户
     * 关注用户前判断当前是否已经关注了用户，避免重复关注，用上面的方法做判断即可
     */
    public Response addUserFoPostUser(FansListInfo fansListInfo) {
        if (getIsFoByCurrentUserId(fansListInfo) > 0) {
            //已经存在
            return new Response(203, "已关注，请勿重复关注", null);
        } else {
            if (iUserDAL.addUserFoPostUser(fansListInfo) > 0) {
                updateUserFoAndFansInfo(fansListInfo);
                //添加消息
                NotifyInfo nInfo = new NotifyInfo();
                nInfo.setIs_foyou(1);//关注消息
                nInfo.setPost_id(0);
                nInfo.setOpr_user_id(fansListInfo.getCurrent_user_id());
                nInfo.setCurrent_user_id(fansListInfo.getPost_user_id());
                notifyDAL.addNotify(nInfo);

                return new Response(200, "关注成功", null);
            } else {
                return new Response(203, "关注失败", null);
            }
        }
    }

    /**
     * 取消关注用户
     */
    public Response delUserFoPostUser(FansListInfo fansListInfo) {
        if (iUserDAL.delUserFoPostUser(fansListInfo) > 0) {
            updateUserFoAndFansInfo(fansListInfo);
            return new Response(200, "取消关注", null);
        } else {
            return new Response(200, "取消关注失败", null);
        }
    }

    /**
     * 关注和取消关注用户后，更新当前用户与被关注/被取消关注用户的关注人数
     * 这里操作的人较多，建议使用存储过程一步完成
     *
     * @返回值 error, 如果值=0，则说明运行成功，不为0则运行失败
     */
    public boolean updateUserFoAndFansInfo(FansListInfo fansListInfo) {
        if (iUserDAL.updateUserFoAndFansInfo(fansListInfo) == 0) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 查询当前用户关注的用户id集合
     */
    public String getCurrentUserFoUserList(Pager pager) {
        String ids = "";
        List<FansListInfo> foUserList = iUserDAL.getCurrentUserFoUserList(pager);

        for (FansListInfo foUser : foUserList) {
            ids += foUser.getFans_fo_id() + ",";
        }
        if (ids != "") {
            ids = ids.substring(0, ids.length() - 1);
            return ids;
        }
        return ids;
    }

    /**
     * 更新认证信息
     */
    public Response updateUserAuth(UserInfo userInfo){
        if(iUserDAL.updateUserAuth(userInfo)>0){
            return new Response(200,"认证成功",null);
        }else{
            return new Response(203,"认证失败",null);
        }
    }

    /**
     * 重新获取当前用户基本信息，用于刷新
     */
    public Response getUserInfoByUserId(UserInfo userInfo){
        return new Response(200,"重新获取用户信息",iUserDAL.getUserInfoByUserId(userInfo));
    }
}
